package org.example.domain.strategy.service.rule.chain.factory;


import lombok.*;
import org.example.domain.strategy.model.entity.StrategyEntity;
import org.example.domain.strategy.repository.IStrategyRepository;
import org.example.domain.strategy.service.rule.chain.ILogicChain;
import org.springframework.stereotype.Service;

import java.util.Map;

/**
 * 责任链工厂
 */
@Service
public class DefaultChainFactory {


    private final Map<String, ILogicChain> logicChainGroup;
    protected IStrategyRepository repository;

    public DefaultChainFactory(Map<String, ILogicChain> logicChainGroup, IStrategyRepository repository) {
        this.logicChainGroup = logicChainGroup;
        this.repository = repository;
    }

    /**
     * 通过策略Id构建责任链
     */
    public ILogicChain openLogicChain(Long strategyId){

        StrategyEntity strategy = repository.queryStrategyEntityByStrategyId(strategyId);
        String[] ruleModels = strategy.ruleModels();

        if(null == ruleModels || 0 == ruleModels.length) return logicChainGroup.get("rule_default");

        //按照配置顺序装填用户配置的责任链：rule_blacklist,rule_weight【注意此数据从Redis缓存中获取，如果更新库表，记得在测试阶段手动处理缓存】
        ILogicChain logicChain = logicChainGroup.get(ruleModels[0]);
        ILogicChain current = logicChain;
        for(int i=1;i<ruleModels.length;i++){
            ILogicChain nextChain = logicChainGroup.get(ruleModels[i]);
            current = current.appendNext(nextChain);
        }

        //责任链的最后装填默认的责任链
        current.appendNext(logicChainGroup.get("rule_default"));

        return logicChain;
    }


    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    public static class StrategyAwardVO{

        //奖品ID，内部流转使用
        private Integer awardId;
        //抽奖逻辑
        private String logicModel;
        /**
         * 抽奖奖品规则
         */
        private String awardRuleValue;
    }


    @Getter
    @AllArgsConstructor
    public enum logicModel{

        RULE_DEFAULT("rule_default","默认抽奖"),
        RULE_BLACKLIST("rule_blacklist","黑名单抽奖"),
        RULE_WEIGHT("rule_weight","权重规则"),
        ;

        private final String code;
        private final String info;
    }


}
